/*******************************************************************************
* Project: QSAR(Cute Software Architecture) 
*
* Copyright: Copyright(C) 2024 by YuetingBen, All Rights Reserved
*
* File name: CanDrv.c
*
* Brief: ;
*
* Author: Yueting.Ben
*
* Module: CanDrv
*
*******************************************************************************/

/** HEADER FILES **/
#include "CanDrv.h"


/** MACRO DEFINITION **/


/** TYPEDEF DEFINITION **/


/** LOCAL DATA DECLARATION **/


/** GLOBAL DATA DECLARATION **/


/** LOCAL FUNCTION DECLARATION **/
#define CAN_POLLING_NUMBER    5u


typedef struct
{
    CAN_TxHeaderTypeDef t_canHeader;
    uint8* bufferPtr;
    uint8 u8_indication;
    PduIdType swPduHandle;
}CAN_FRAME_TX_INFO_S;


typedef struct
{
    CAN_RxHeaderTypeDef t_canHeader;
    uint8 u8_buffer[8];
    uint8 u8_indication;
}CAN_FRAME_RX_INFO_S;


typedef struct
{
    CAN_FRAME_TX_INFO_S s_canTxFrameInfo[CAN_POLLING_NUMBER];
    CAN_FRAME_RX_INFO_S s_canRxFrameInfo[CAN_POLLING_NUMBER];
    uint8 u8_frameTxIndex;
    uint8 u8_frameRxIndex;
    Can_ControllerStateType ControllerState;
}CAN_INFO_S;

static CAN_INFO_S s_CanInfo;


/** GLOBAL FUNCTION DECLARATION **/

Std_ReturnType Can_SetBaudrate(
    uint8 Controller, 
    uint16 BaudRateConfigID
);

Std_ReturnType Can_SetControllerMode(
    uint8 Controller, 
    Can_ControllerStateType Transition
);

void Can_DisableControllerInterrupts(
    uint8 Controller
);

void Can_EnableControllerInterrupts(
    uint8 Controller
);

void Can_CheckWakeup(
    uint8 Controller
);

Std_ReturnType Can_GetControllerErrorState(
    uint8 ControllerId, 
    Can_ErrorStateType* ErrorStatePtr
);

Std_ReturnType Can_GetControllerMode(
    uint8 Controller,
    Can_ControllerStateType* ControllerModePtr
);

Std_ReturnType Can_GetControllerRxErrorCounter(
    uint8 ControllerId, 
    uint8* RxErrorCounterPtr
);

Std_ReturnType Can_GetControllerTxErrorCounter(
    uint8 ControllerId, 
    uint8* TxErrorCounterPtr
);

Std_ReturnType Can_GetCurrentTime(
    uint8 ControllerId, 
    Can_TimeStampType* timeStampPtr
);

void Can_EnableEgressTimeStamp(
    Can_HwHandleType Hth
);

Std_ReturnType Can_GetEgressTimeStamp(
    PduIdType TxPduId, 
    Can_HwHandleType Hth,
    Can_TimeStampType* timeStampPtr
);

Std_ReturnType Can_GetIngressTimeStamp(
    Can_HwHandleType Hrh, 
    Can_TimeStampType* timeStampPtr
);

Std_ReturnType Can_Write(
    Can_HwHandleType Hth, 
    const Can_PduType* PduInfo
);

boolean Can_LPDU_CalloutFunction(
    uint8 Hrh, 
    Can_IdType CanId, 
    uint8 CanDataLegth, 
    const uint8* CanSduPtr
);

void Can_MainFunction_Write(
    void
);

void Can_MainFunction_Read(
    void
);

void Can_MainFunction_BusOff(
    void
);

void Can_MainFunction_Wakeup(
    void
);

void Can_MainFunction_Mode(
    void
);

void Can_GetVersionInfo(
    Std_VersionInfoType* versionInfo
);

void Can_Init(
    const Can_ConfigType* Config
);

void Can_MainFunction(
    void
);

/** LOCAL DATA **/


/** GLOBAL DATA **/


/** LOCAL FUNCTION **/


/** GLOBAL FUNCTION **/

/*******************************************************************************
* -Name         Can_SetBaudrate
* -Brief        This service shall set the baud rate configuration of the CAN controller. Depending on necessary baud rate 
*               modifications the controller might have to reset.
* -Details      None
* -Param[in]    Controller: CAN controller, whose baud rate shall be set
* -Param[in]    BaudRateConfigID: references a baud rate configuration by ID (see CanControllerBaudRateConfigID)
* -Return       E_OK: Service request accepted, setting of (new) baud rate started
*               E_NOT_OK: Service request not accepted
*******************************************************************************/
Std_ReturnType Can_SetBaudrate(
    uint8 Controller, 
    uint16 BaudRateConfigID
)
{
    
}

/*******************************************************************************
* -Name         Can_SetControllerMode
* -Brief        This function performs software triggered state transitions of the CAN controller State machine
* -Details      None
* -Param[in]    Controller: CAN controller for which the status shall be changed
* -Param[in]    Transition: Transition value to request new CAN controller state
* -Return       E_OK: request accepted
*               E_NOT_OK: request not accepted, a development error occurred
*******************************************************************************/
Std_ReturnType Can_SetControllerMode(
    uint8 Controller, 
    Can_ControllerStateType Transition
)
{
    CAN_INFO_S* canInfoPtr = (CAN_INFO_S*)&s_CanInfo;
    
    switch(Transition)
    {
        case CAN_CS_STARTED:
        {
            if(CAN_CS_STARTED != canInfoPtr->ControllerState)
            {
                CAN_NormalMode();
            }
            break;
        }
        case CAN_CS_STOPPED:
        {
            if(CAN_CS_STOPPED != canInfoPtr->ControllerState)
            {
                CAN_SilentMode();
            }
            break;
        }
        case CAN_CS_SLEEP:
        {
            break;
        }
        default:
        {
            break;
        }
    }
    
}

/*******************************************************************************
* -Name         Can_DisableControllerInterrupts
* -Brief        This function disables all interrupts for this CAN controller
* -Details      None
* -Param[in]    Controller: CAN controller for which interrupts shall be disabled
* -Return       None
*******************************************************************************/
void Can_DisableControllerInterrupts(
    uint8 Controller
)
{
    
}

/*******************************************************************************
* -Name         Can_EnableControllerInterrupts
* -Brief        This function disables all interrupts for this CAN controller
* -Details      None
* -Param[in]    Controller: CAN controller for which interrupts shall be re-enabled
* -Return       None
*******************************************************************************/
void Can_EnableControllerInterrupts(
    uint8 Controller
)
{
    
}

/*******************************************************************************
* -Name         Can_CheckWakeup
* -Brief        This function checks if a wakeup has occurred for the given controller
* -Details      None
* -Param[in]    Controller: Controller to be checked for a wakeup
* -Return       E_OK: API call has been accepted
*               E_NOT_OK: API call has not been accepted
*******************************************************************************/
void Can_CheckWakeup(
    uint8 Controller
)
{
    
}

/*******************************************************************************
* -Name         Can_GetControllerErrorState
* -Brief        This service obtains the error state of the CAN controller
* -Details      None
* -Param[in]    ControllerId: Abstracted CanIf ControllerId which is assigned to a CAN controller, which is requested for ErrorState
* -Param[out]   ErrorStatePtr: Pointer to a memory location, where the error state of the CAN controller will be stored
* -Return       E_OK: Error state request has been accepted
*               E_NOT_OK: Error state request has not been accepted
*******************************************************************************/
Std_ReturnType Can_GetControllerErrorState(
    uint8 ControllerId, 
    Can_ErrorStateType* ErrorStatePtr
)
{
    
}

/*******************************************************************************
* -Name         Can_GetControllerMode
* -Brief        This service reports about the current status of the requested CAN controller
* -Details      None
* -Param[in]    Controller: CAN controller for which the status shall be requested
* -Param[out]   ControllerModePtr: Pointer to a memory location, where the current mode of the CAN controller will be stored
* -Return       E_OK: Controller mode request has been accepted
*               E_NOT_OK: Controller mode request has not been accepted
*******************************************************************************/
Std_ReturnType Can_GetControllerMode(
    uint8 Controller,
    Can_ControllerStateType* ControllerModePtr
)
{
    
}

/*******************************************************************************
* -Name         Can_GetControllerRxErrorCounter
* -Brief        None
* -Details      Returns the Rx error counter for a CAN controller. This value might not be available for all CAN controllers, 
*               in which case E_NOT_OK would be returned. Please note that the value of the counter might not be correct at 
*               the moment the API returns it, because the Rx counter is handled asynchronously in hardware. Applications 
*               should not trust this value for any assumption about the current bus state.
* -Param[in]    ControllerId: CAN controller, whose current Rx error counter shall be acquired
* -Param[out]   RxErrorCounterPtr: Pointer to a memory location, where the current Rx error counter of the CAN controller will be stored
* -Return       E_OK: Rx error counter available
*               E_NOT_OK: Wrong ControllerId, or Rx error counter not available
*******************************************************************************/
Std_ReturnType Can_GetControllerRxErrorCounter(
    uint8 ControllerId, 
    uint8* RxErrorCounterPtr
)
{
    
}

/*******************************************************************************
* -Name         Can_GetControllerTxErrorCounter
* -Brief        None
* -Details      Returns the Tx error counter for a CAN controller. This value might not be available for all CAN controllers, 
*               in which case E_NOT_OK would be returned. Please note that the value of the counter might not be correct at 
*               the moment the API returns it, because the Tx counter is handled asynchronously in hardware. Applications 
*               should not trust this value for any assumption about the current bus state
* -Param[in]    ControllerId: CAN controller, whose current Rx error counter shall be acquired
* -Param[out]   TxErrorCounterPtr: Pointer to a memory location, where the current Tx error counter of the CAN controller will be stored
* -Return       E_OK: Tx error counter available
*               E_NOT_OK: Wrong ControllerId, or Tx error counter not available
*******************************************************************************/
Std_ReturnType Can_GetControllerTxErrorCounter(
    uint8 ControllerId, 
    uint8* TxErrorCounterPtr
)
{
    
}

/*******************************************************************************
* -Name         Can_GetCurrentTime
* -Brief        Returns a time value out of the HW registers according to the capability of the HW
* -Details      None
* -Param[in]    ControllerId: Index of the addresses CAN controller
* -Param[out]   timeStampPtr: current time stamp
* -Return       E_OK: successful
*               E_NOT_OK: failed
*******************************************************************************/
Std_ReturnType Can_GetCurrentTime(
    uint8 ControllerId, 
    Can_TimeStampType* timeStampPtr
)
{
    
}

/*******************************************************************************
* -Name         Can_EnableEgressTimeStamp
* -Brief        Activates egress time stamping on a dedicated HTH.
*               Some HW does store once the egress time stamp marker and some HW needs it always before transmission. 
*               There will be no "disable" functionality, due to the fact, that the message type is always "time stamped" 
*               by network design
* -Details      None
* -Param[in]    Hth: information which HW-transmit handle shall be used for enabling the time stamp.
* -Return       None
*******************************************************************************/
void Can_EnableEgressTimeStamp(
    Can_HwHandleType Hth
)
{
    
}

/*******************************************************************************
* -Name         Can_GetEgressTimeStamp
* -Brief        Reads back the egress time stamp on a dedicated message object. It needs to be called within the TxConfirmation() function.
* -Details      None
* -Param[in]    TxPduId: L-PDU handle of CAN L-PDU for which the time stamp shall be returned
* -Param[in]    Hth: HW-transmit handle for which the egress timestamp shall be retrieved
* -Param[out]   timeStampPtr: current time stamp
* -Return       E_OK: success
*               E_NOT_OK: failed to read time stamp.
*******************************************************************************/
Std_ReturnType Can_GetEgressTimeStamp(
    PduIdType TxPduId, 
    Can_HwHandleType Hth,
    Can_TimeStampType* timeStampPtr
)
{
    
}

/*******************************************************************************
* -Name         Can_GetIngressTimeStamp
* -Brief        Reads back the ingress time stamp on a dedicated message object. It needs to be called within the RxIndication() function
* -Details      None
* -Param[in]    TxPduId: L-PDU handle of CAN L-PDU for which the time stamp shall be returned
* -Param[in]    Hrh: HW-receive handle for which the ingress timestamp shall be retrieved
* -Param[out]   timeStampPtr: current time stamp
* -Return       E_OK: success
*               E_NOT_OK: failed to read time stamp.
*******************************************************************************/
Std_ReturnType Can_GetIngressTimeStamp(
    Can_HwHandleType Hrh, 
    Can_TimeStampType* timeStampPtr
)
{
    
}

/*******************************************************************************
* -Name         Can_Write
* -Brief        This function is called by CanIf to pass a CAN message to CanDrv for transmission
* -Details      None
* -Param[in]    Hth: information which HW-transmit handle shall be used for transmit. Implicitly this is also the information about 
*                    the controller to use because the Hth numbers are unique inside one hardware unit
* -Param[in]    PduInfo: Pointer to SDU user memory, Data Length and Identifier
* -Param[out]   None
* -Return       E_OK: Write command has been accepted
*               E_NOT_OK: development error occurred
*               CAN_BUSY: No TX hardware buffer available or pre-emptive call of Can_Write that can't be implemented re-entrant (see Can_ReturnType)
*******************************************************************************/
Std_ReturnType Can_Write(
    Can_HwHandleType Hth, 
    const Can_PduType* PduInfo
)
{
    Std_ReturnType retval = E_OK;
    CAN_TxHeaderTypeDef t_canHeaderType;
    uint32 u32_txMailbox;
    
    s_CanInfo.s_canTxFrameInfo[s_CanInfo.u8_frameTxIndex].t_canHeader.StdId = PduInfo->id;
    s_CanInfo.s_canTxFrameInfo[s_CanInfo.u8_frameTxIndex].t_canHeader.DLC = PduInfo->length;
    s_CanInfo.s_canTxFrameInfo[s_CanInfo.u8_frameTxIndex].bufferPtr = PduInfo->sdu;
    s_CanInfo.s_canTxFrameInfo[s_CanInfo.u8_frameTxIndex].swPduHandle = PduInfo->swPduHandle;
    s_CanInfo.s_canTxFrameInfo[s_CanInfo.u8_frameTxIndex].u8_indication = SET;
    s_CanInfo.u8_frameTxIndex++;
    
    if(CAN_POLLING_NUMBER <= s_CanInfo.u8_frameTxIndex)
    {
        s_CanInfo.u8_frameTxIndex = 0u;
    }

    return(retval);
}


/*******************************************************************************
* -Name         CAN_Read
* -Brief        This function is called by CanIf to pass a CAN message to CanDrv for transmission
* -Details      None
* -Param[in]    hcan: 
* -Param[out]   None
* -Return       None
*******************************************************************************/
void CAN_Read(
    CAN_HandleTypeDef *hcan
)
{
    HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO0);
    HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &(s_CanInfo.s_canRxFrameInfo[s_CanInfo.u8_frameRxIndex].t_canHeader),  s_CanInfo.s_canRxFrameInfo[s_CanInfo.u8_frameRxIndex].u8_buffer);
    s_CanInfo.s_canRxFrameInfo[s_CanInfo.u8_frameRxIndex].u8_indication = SET;
    
    s_CanInfo.u8_frameRxIndex++;
    if(CAN_POLLING_NUMBER <= s_CanInfo.u8_frameRxIndex)
    {
        s_CanInfo.u8_frameRxIndex = 0u;
    }
}

/*******************************************************************************
* -Name         Can_LPDU_CalloutFunction
* -Brief        L-PDU callout function
* -Details      None
* -Param[in]    Hrh: HW-receive handle for which the ingress timestamp shall be retrieved
* -Param[in]    CanId: Received CAN Identifier
* -Param[in]    CanDataLegth: Received CAN data length
* -Param[in]    CanSduPtr: pointer to SDU
* -Param[out]   None
* -Return       E_OK: Ok
*               E_NOT_OK: Not Ok
*******************************************************************************/
boolean Can_LPDU_CalloutFunction(
    uint8 Hrh, 
    Can_IdType CanId, 
    uint8 CanDataLegth, 
    const uint8* CanSduPtr
)
{
    
}

/*******************************************************************************
* -Name         Can_MainFunction_Write
* -Brief        This function performs the polling of TX confirmation when CAN_TX_PROCESSING is set to POLLING
* -Details      None
* -Param[in]    None
* -Param[out]   None
* -Return       None
*******************************************************************************/
void Can_MainFunction_Write(
    void
)
{
    uint8 u8_i;
    CAN_FRAME_TX_INFO_S* ptr_canFrameInfo;
    uint32 u32_txMailbox;
    
    for(u8_i = 0; u8_i < CAN_POLLING_NUMBER; u8_i++)
    {
        ptr_canFrameInfo = &s_CanInfo.s_canTxFrameInfo[u8_i];
        if(SET == ptr_canFrameInfo->u8_indication)
        {
            HAL_CAN_AddTxMessage(&hcan, &(ptr_canFrameInfo->t_canHeader), ptr_canFrameInfo->bufferPtr, &u32_txMailbox);
            ptr_canFrameInfo->u8_indication = RESET;
            CanIf_TxConfirmation(ptr_canFrameInfo->swPduHandle);
            break;
        }
    }
}

/*******************************************************************************
* -Name         Can_MainFunction_Read
* -Brief        This function performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING
* -Details      None
* -Param[in]    None
* -Param[out]   None
* -Return       None
*******************************************************************************/
void Can_MainFunction_Read(
    void
)
{
    uint8 u8_i;
    CAN_FRAME_RX_INFO_S* ptr_canFrameInfo;
    Can_HwType mailbox;
    PduInfoType pduInfo;

    for(u8_i = 0; u8_i < CAN_POLLING_NUMBER; u8_i++)
    {
        ptr_canFrameInfo = &s_CanInfo.s_canRxFrameInfo[u8_i];
        if(SET == ptr_canFrameInfo->u8_indication)
        {
            mailbox.CanId = ptr_canFrameInfo->t_canHeader.StdId;
            pduInfo.SduLength = ptr_canFrameInfo->t_canHeader.DLC;
            pduInfo.SduDataPtr = ptr_canFrameInfo->u8_buffer;
            CanIf_RxIndication (&mailbox, &pduInfo);

            ptr_canFrameInfo->u8_indication = RESET;
        }
    }
}

/*******************************************************************************
* -Name         Can_MainFunction_BusOff
* -Brief        This function performs the polling of bus-off events that are configured statically as 'to be polled'.
* -Details      None
* -Param[in]    None
* -Param[out]   None
* -Return       None
*******************************************************************************/
void Can_MainFunction_BusOff(
    void
)
{
    
}

/*******************************************************************************
* -Name         Can_MainFunction_Wakeup
* -Brief        This function performs the polling of wake-up events that are configured statically as 'to be polled'.
* -Details      None
* -Param[in]    None
* -Param[out]   None
* -Return       None
*******************************************************************************/
void Can_MainFunction_Wakeup(
    void
)
{
    
}

/*******************************************************************************
* -Name         Can_MainFunction_Mode
* -Brief        This function performs the polling of CAN controller mode transitions
* -Details      None
* -Param[in]    None
* -Param[out]   None
* -Return       None
*******************************************************************************/
void Can_MainFunction_Mode(
    void
)
{
    
}


/*******************************************************************************
* -Name         Can_GetVersionInfo
* -Brief        Returns the version information of this module 
* -Details      None
* -Param[out]   versioninfo: Pointer to the version information of this module
* -Return       None          
*******************************************************************************/
void Can_GetVersionInfo(
    Std_VersionInfoType* versionInfo
)
{
    versionInfo->vendorID = (uint16)YSAR_VENDOR_ID;
    versionInfo->moduleID = (uint8)CAN_MODULE_ID;
    versionInfo->sw_major_version = (uint8)CAN_SW_MAJOR_VERSION;
    versionInfo->sw_minor_version = (uint8)CAN_SW_MINOR_VERSION;
    versionInfo->sw_patch_version = (uint8)CAN_SW_PATCH_VERSION;
}

/*******************************************************************************
* -Name         Can_Init
* -Brief        This function initializes the module 
* -Details      None
* -Param[in]    Config: Pointer to driver configuration
* -Return       None          
*******************************************************************************/
void Can_Init(
    const Can_ConfigType* Config
)
{
    
}

/*******************************************************************************
* -Name         Can_MainFunction
* -Brief        Cyclic function for CAN module 
* -Details      None
* -Param[in]    None
* -Return       None          
*******************************************************************************/
void Can_MainFunction(
    void
)
{
    Can_MainFunction_Write();
    Can_MainFunction_Read();
}


